package cn.wolfcode.shop.cloud.service.impl;

import cn.wolfcode.shop.cloud.common.BusinessException;
import cn.wolfcode.shop.cloud.common.Result;
import cn.wolfcode.shop.cloud.domain.Good;
import cn.wolfcode.shop.cloud.feign.GoodsFeignApi;
import cn.wolfcode.shop.cloud.mapper.SeckillMapper;
import cn.wolfcode.shop.cloud.redis.RedisService;
import cn.wolfcode.shop.cloud.service.ISeckillService;
import cn.wolfcode.shop.cloud.util.GoodCodeMessage;
import cn.wolfcode.shop.cloud.util.SeckillGoodVO;
import cn.wolfcode.shop.cloud.util.SeckillKeyPrefix;
import cn.wolfcode.shop.cloud.web.controller.SeckillOrderController;
import cn.wolfode.shop.cloud.domain.SeckillGood;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class SeckillServiceImpl implements ISeckillService {
    @Autowired
    private SeckillMapper seckillMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private GoodsFeignApi goodsFeignApi;
    @Override
    public List<SeckillGoodVO> query() {
        //1、查询出秒杀商品的数据
        List<SeckillGood> seckillGoods = seckillMapper.querySeckGoods();
        List<SeckillGoodVO> seckillGoodVOS = querySeckillGood(seckillGoods);
        return seckillGoodVOS;
    }

    private List<SeckillGoodVO> querySeckillGood(List<SeckillGood> seckillGoods) {
        //2、将秒杀商品数据的商品id储存在set集合中，进行去重
        Set<Long> goodIds = new HashSet<>();
        for (int i = 0; i < seckillGoods.size(); i++) {
            goodIds.add(seckillGoods.get(i).getGoodId());
        }
        //3、将set集合转换成list集合(用户在查询远程商品服务时，可以用到fori循环)
        ArrayList<Long> aGoodIds = new ArrayList<>(goodIds);
        //4、通过去重后的id集合通过远程调用商品服务获取商品数据集合，并封装到map集合中(key是商品id，value是商品对象)
        Result<List<Good>> result = goodsFeignApi.queryByIds(aGoodIds);
        if(result == null || result.getCode()!=200){
            throw new BusinessException(GoodCodeMessage.REMOTE_GOOD_ERROR);
        }
        List<Good> goods = result.getData();
        Map<Long,Good> map = new HashMap();
        for (Good good:goods) {
            map.put(good.getId(),good);
        }
        //5、循环迭代秒杀数据，通过秒杀数据中的上面的商品id，获取商品数据，然后进行聚合，封装到vo对象中
        List<SeckillGoodVO> seckillGoodVOS = new ArrayList<>();
        for(SeckillGood seckillGood:seckillGoods){
            Good good = map.get(seckillGood.getGoodId());
            SeckillGoodVO seckillGoodVO = new SeckillGoodVO();
            seckillGoodVO.setGoodDetail(good.getGoodDetail());
            seckillGoodVO.setGoodImg(good.getGoodImg());
            seckillGoodVO.setGoodName(good.getGoodName());
            seckillGoodVO.setGoodPrice(good.getGoodPrice());
            seckillGoodVO.setGoodStock(good.getGoodStock());
            seckillGoodVO.setId(seckillGood.getId());
            seckillGoodVO.setEndDate(seckillGood.getEndDate());
            seckillGoodVO.setGoodId(seckillGood.getGoodId());
            seckillGoodVO.setSeckillPrice(seckillGood.getSeckillPrice());
            seckillGoodVO.setStartDate(seckillGood.getStartDate());
            seckillGoodVO.setStockCount(seckillGood.getStockCount());

            seckillGoodVOS.add(seckillGoodVO);
        }
        return seckillGoodVOS;
    }

    @Override
    public SeckillGoodVO goodDetail(Long seckillId) {
        //通过秒杀商品id查询秒杀商品
        SeckillGood seckillGood = seckillMapper.queryBySeckillId(seckillId);
        //将秒杀商品存入集合中
        List<SeckillGood> list = new ArrayList<>();
        list.add(seckillGood);
        //通过该集合查询vo对象
        List<SeckillGoodVO> seckillGoodVOS = querySeckillGood(list);
        SeckillGoodVO seckillGoodVO = seckillGoodVOS.get(0);
        return seckillGoodVO;
    }

    @Override
    public void incrCount(Long goodId) {
        seckillMapper.incrCount(goodId);
    }

    @Override
    public void incrRedis(Long goodId) {
        //从数据库中取出vo对象
        SeckillGoodVO seckillGoodVO = this.goodDetail(goodId);
        //将数据库中的库存设置到redis中去
        redisService.set(SeckillKeyPrefix.SECKILL_REDIS_COUNT,goodId+"", seckillGoodVO.getGoodStock());
    }

    @Override
    public void updateFlag(Long aLong) {
        SeckillOrderController.isflag.put(aLong,false);
    }
}
